package model.doe;

import java.util.HashMap;
import java.util.Map;

public class BifocalLens extends AbstractDoe {
	private double r, f1, f2, wl, s;
	private boolean withLens;

	public BifocalLens(double r, double f1, double f2, double wl, double s,
			boolean sign) {
		this.f1 = f1;
		this.f2 = f2;
		this.r = r;
		this.wl = wl / 1000;
		this.s = s;
		this.withLens = sign;
		widthPointsNumber = (int) (2*r / s);
		heightPointsNumber = (int) (2*r / s);
		Map <String, Double> minMax = getBifocalLensMinAndMax();
		maximumValue = minMax.get("max");
		minValue = minMax.get("min");
	}

	private Map<String, Double> getBifocalLensMinAndMax() {
		double fd2 = 2 * f1 * f2 / (f2 - f1);
		Map<String, Double> minMaxMap = new HashMap<String, Double>();
		if (this.withLens) {
			minMaxMap.put("min", Double.valueOf(0));
			minMaxMap.put("max", Math.PI);
		} else {
			int i = (int) (r * r / (wl * fd2)); // must be int
			double rr = bifocalLensFun(Math.sqrt(i * wl * fd2));
			minMaxMap.put("min", bifocalLensFun(r));
			if (minMaxMap.get("min") > rr)
				minMaxMap.put("min", rr);
			minMaxMap.put("max", bifocalLensFun(Math.sqrt(wl * fd2)));
			if (minMaxMap.get("max") < 0)
				minMaxMap.put("max", Double.valueOf(0));
		}
		return minMaxMap;
	}

	private double bifocalLensFun(double rr) {
		double fd1, fd2, ph;

		fd1 = 2 * f1 * f2 / (f1 + f2);
		fd2 = 2 * f1 * f2 / (f2 - f1);

		ph = Math.abs((Math.PI * rr * rr / (fd2 * wl)) % (2 * Math.PI));
		ph = (ph > Math.PI) ? Math.PI : 0;

		if (rr>r){
			return 0;
		}
		
		if (!withLens)
			return (ph);
		else
			return (ph - Math.PI * rr * rr / (fd1 * wl));

	}
	
	@Override
	public double run(int i, int j) {
		
		return bifocalLensFun(Math.sqrt(s * j
				* s * j + s * i * s * i));
	}



}
